"use strict";
!function (win) {
  let _vue

  /**
   * 实现的功能
   * 1、模拟实现路由
   * 2、在所有vue实例及其所有组件上都能使用 router 的方法
   * */ 
  class MyRouter {
    static install (Vue, options) {
      // 1. 是否已经安装
      if (this.install.installer) return
      this.install.installer = true
  
      // 2. 缓存 Vue 类
      _vue = Vue
      // 将路由方法挂在到所有 vue 组件实例上
      _vue.mixin({
        beforeCreate() {
          if (this.$options.router) {
            _vue.prototype.$router = this.$options.router
          }
        }
      })
    }

    constructor(options) {
      this.options = options
      this.mapRouterData = {}
      this.path = _vue.observable({
        current: '/'
      })

      
      this.init()
    }

    init() {
      this.createMapRouterData()
      this.initComponent()
      this.initEvent()
    }

    // 创建路由的映射数据，将路径对应的组件关联起来并保存
    createMapRouterData() {
      this.options.router && this.options.router.forEach(routerItem => {
        this.mapRouterData[routerItem.path] = routerItem.components
      })
    }

    initComponent() {
      _vue.component('routerLink', {
        name: 'RouterLink',
        render(c) {
          return c('a', {
            attrs: {
              href: this.to
            },
            on: {
              click: this.onSkipPage
            },
          }, this.$slots.default)
        },
        props: {
          to: {
            type: String,
            required: true
          }
        },
        methods: {
          // 跳转页面
          onSkipPage(e) {
            e.preventDefault()
            this.$router.path.current = this.to
            history.pushState({}, '', this.to)
          }
        }
      })

      const self = this
      _vue.component('routerView', {
        name: 'RouterView',
        render(c) {
          const component = self.mapRouterData[self.path.current]
          return c(component)
        },
      })
    }

    initEvent() {
      window.addEventListener('popstate', (event) => {
        this.path.current = window.location.pathname
      })
    }
  }

  win.MyRouter = MyRouter
}(window)

